/**
 * AI响应生成模块
 */
import { ChatMessage } from '../core/types.ts';
import { ensureApiInitialized } from './apiInvoke.ts';
import { getInvoke } from './apiInvoke.ts';
import { getApiKeyForModel, getProviderForModel, getHumanReadableError } from './modelUtils.ts';
import { intelligentCompressHistory } from './messageCompression.ts';
import { getApiClient, handleApiError, callApiDirectly } from './apiClient.ts';
import { settings } from '../core/settings.ts';
import { ChatCompletionMessageParam } from 'openai/resources';

/**
 * AI响应类型定义
 */
export interface AIResponse {
    success: boolean;
    error?: string;
    response?: string;
    content?: string;
}

/**
 * AI请求选项类型定义
 */
export interface AIRequestOptions {
    model?: string;
    maxTokens?: number;
    temperature?: number;
    pinnedMessages?: number[];
    streamCallback?: (chunk: string) => void;
}

/**
 * 使用OpenAI SDK生成AI响应
 */

// 定义响应类型
export interface OpenAIResponse {
    success: boolean;
    content?: string;
    error?: string;
    response?: any;
}

// 定义请求选项类型
export interface OpenAIRequestOptions {
    model?: string;
    temperature?: number;
    maxTokens?: number;
}

// 默认选项
const defaultOptions: OpenAIRequestOptions = {
    maxTokens: 1000,
    temperature: 0.7,
    model: 'deepseek-chat',
};

// 辅助函数：将字符串分成小块
function splitIntoChunks(text: string, chunkSize: number = 5): string[] {
    const chunks: string[] = [];
    let currentChunk = '';
    const words = text.split(' ');

    for (const word of words) {
        if (currentChunk && currentChunk.split(' ').length >= chunkSize) {
            chunks.push(currentChunk);
            currentChunk = word;
        } else {
            currentChunk = currentChunk ? `${currentChunk} ${word}` : word;
        }
    }

    if (currentChunk) {
        chunks.push(currentChunk);
    }

    return chunks;
}

/**
 * 生成AI响应 - 与AIChatPanel兼容的接口
 * @param messages 消息数组或提示字符串
 * @param options 请求选项或上下文字符串
 * @returns AI响应
 */
export async function generateAIResponse(
    messages: ChatMessage[] | string,
    options: AIRequestOptions | string = {},
    callbackOrOptions?: ((text: string) => void) | OpenAIRequestOptions
): Promise<AIResponse | OpenAIResponse> {
    // 检查是否使用了旧的调用方式 (messages是字符串)
    if (typeof messages === 'string') {
        return generateAIResponseWithPrompt(
            messages,
            typeof options === 'string' ? options : '',
            typeof callbackOrOptions === 'function' ? callbackOrOptions : callbackOrOptions as OpenAIRequestOptions
        );
    }

    // 使用新的调用方式 (messages是数组)
    try {
        // 确保API初始化完成
        const initialized = await ensureApiInitialized();
        if (!initialized) {
            return {
                success: false,
                error: '无法初始化API服务'
            };
        }

        // 默认选项
        const defaultRequestOptions = {
            model: 'deepseek-chat',
            maxTokens: 4000,
            temperature: 0.7,
        };

        // 合并选项
        const mergedOptions = {
            ...defaultRequestOptions,
            ...(options as AIRequestOptions)
        };

        // 获取模型名称
        const modelName = mergedOptions.model || defaultRequestOptions.model;

        // 加载所有设置
        const allSettings = await settings.getAll();
        const selectedModel = allSettings.selected_model || 'deepseek-chat';

        // 使用设置中的模型或默认值
        const finalModelName = modelName === defaultRequestOptions.model ? selectedModel : modelName;

        console.log(`使用模型: ${finalModelName}`);

        // 验证messages是否为数组
        if (!Array.isArray(messages) || messages.length === 0) {
            return {
                success: false,
                error: '无效的消息格式：messages必须是非空数组'
            };
        }

        // 处理流式响应
        if (mergedOptions.streamCallback) {
            console.log('使用流式输出');

            try {
                // 使用直接API调用方式，启用真正的流式传输
                console.log(`发送流式API请求: model=${finalModelName}, temperature=${mergedOptions.temperature}, maxTokens=${mergedOptions.maxTokens}`);

                // 转换消息格式 - 简化消息结构，只保留role和content字段
                const formattedMessages = messages.map(msg => ({
                    role: msg.role === 'user' ? 'user' : (msg.role === 'system' ? 'system' : 'assistant'),
                    content: typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content)
                }));

                let fullResponse = '';

                // 使用流式API获取响应
                const response = await callApiDirectly(
                    finalModelName,
                    formattedMessages,
                    {
                        temperature: mergedOptions.temperature || defaultRequestOptions.temperature,
                        max_tokens: mergedOptions.maxTokens || defaultRequestOptions.maxTokens,
                        stream: true,
                        onChunk: (chunk) => {
                            // 直接将chunk发送给回调函数，只传递当前新接收的chunk
                            if (chunk && chunk.length > 0) {
                                console.log(`[AI响应] 收到新块: ${chunk.length}字符`);
                                mergedOptions.streamCallback?.(chunk);
                                fullResponse += chunk;
                            }
                        }
                    }
                );

                // 流式传输已完成，检查fullResponse
                console.log(`流式传输完成，总响应长度: ${fullResponse.length}`);

                return {
                    success: true,
                    response: fullResponse,
                    content: fullResponse
                };
            } catch (error) {
                console.error('API请求失败:', error);

                // 发送错误消息到流
                mergedOptions.streamCallback?.('\n\n请求失败：');
                mergedOptions.streamCallback?.(`\n\n${handleApiError(error, finalModelName)}`);

                    return {
                        success: false,
                    error: handleApiError(error, finalModelName)
                };
            }
        } else {
            // 不使用流式响应
            try {
                console.log(`发送API请求: model=${finalModelName}, temperature=${mergedOptions.temperature}, maxTokens=${mergedOptions.maxTokens}`);

                // 转换消息格式
                const formattedMessages = messages.map(msg => ({
                    role: msg.role === 'user' ? 'user' : (msg.role === 'system' ? 'system' : 'assistant'),
                    content: typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content)
                }));

                const response = await callApiDirectly(
                    finalModelName,
                    formattedMessages,
                    {
                        temperature: mergedOptions.temperature || defaultRequestOptions.temperature,
                        max_tokens: mergedOptions.maxTokens || defaultRequestOptions.maxTokens,
                        stream: false
                    }
                );

                // 获取响应内容
                const content = response.choices?.[0]?.message?.content || '';
                if (typeof content !== 'string') {
                    console.error('API返回了非字符串内容:', content);
                    throw new Error('API返回了无效的响应格式');
                }

                console.log(`收到响应, 长度: ${content.length}`);

                return {
                    success: true,
                    response: content,
                    content
                };
            } catch (error) {
                console.error('API请求失败:', error);
                return {
                    success: false,
                    error: handleApiError(error, finalModelName)
                };
            }
        }
    } catch (error) {
        console.error('生成AI响应发生错误:', error);
        return {
            success: false,
            error: `生成AI响应失败: ${error instanceof Error ? error.message : String(error)}`
        };
    }
}

/**
 * 使用提示字符串生成AI响应
 * @param prompt 用户提示
 * @param context 上下文信息
 * @param optionsOrCallback 选项或回调函数
 * @returns AI响应
 */
export async function generateAIResponseWithPrompt(
    prompt: string,
    context: string = '',
    optionsOrCallback?: OpenAIRequestOptions | ((text: string) => void)
): Promise<OpenAIResponse> {
    try {
        console.log(`生成AI响应，提示长度: ${prompt.length}, 上下文: ${context ? '有' : '无'}`);

        let options: OpenAIRequestOptions = { ...defaultOptions };
        let streamCallback: ((text: string) => void) | undefined;

        // 处理参数
        if (typeof optionsOrCallback === 'function') {
            streamCallback = optionsOrCallback;
        } else if (optionsOrCallback) {
            options = { ...defaultOptions, ...optionsOrCallback };
        }

        // 加载所有设置
        const allSettings = await settings.getAll();
        console.log(`已加载设置: 选择的模型: ${allSettings.selected_model || '未设置'}`);

        // 确保模型名称不为undefined
        const modelName: string = options.model || allSettings.selected_model || defaultOptions.model || 'deepseek-chat';
        console.log(`使用模型: ${modelName}`);

        // 构建消息
        const messages: ChatCompletionMessageParam[] = [
            {
                role: 'system',
                content: `你是一个小说写作助手，帮助作者改进他们的文本。请提供有用的建议和反馈。${context ? `当前上下文: ${context}` : ''}`
            },
            {
                role: 'user',
                content: prompt
            }
        ];

        // 获取API客户端
        const { client, error } = await getApiClient(modelName);

        if (error) {
            console.error(`获取API客户端失败: ${error}`);
            return {
                success: false,
                error
            };
        }

        if (!client) {
            return {
                success: false,
                error: "无法创建API客户端"
            };
        }

        // 对流式响应部分进行修复
        if (streamCallback) {
            console.log('使用模拟流式输出');

            // 开始模拟流式响应
            let initialResponse = "正在分析您的文本...";
            let initialResponseParts = initialResponse.split(' ');
            let partIndex = 0;
            let fullResponse = '';

            const simulatedStreamInterval = window.setInterval(() => {
                if (partIndex < initialResponseParts.length) {
                    let part = initialResponseParts[partIndex];
                    if (partIndex > 0) part = ' ' + part;
                    streamCallback?.(part);
                    fullResponse += part;
                    partIndex++;
                } else {
                    // 初始响应已完全输出
                    clearInterval(simulatedStreamInterval);
                }
            }, 100);

            try {
                // 使用直接API调用方式
                console.log(`发送API请求: model=${modelName}, temperature=${options.temperature}, maxTokens=${options.maxTokens}`);

                // 转换消息格式 - 简化消息结构，只保留role和content字段
                const formattedMessages = messages.map(msg => ({
                    role: msg.role === 'user' ? 'user' : (msg.role === 'system' ? 'system' : 'assistant'),
                    content: typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content)
                }));

                const response = await callApiDirectly(
                    modelName,
                    formattedMessages,
                    {
                        temperature: options.temperature || defaultOptions.temperature,
                        max_tokens: options.maxTokens || defaultOptions.maxTokens,
                        stream: false
                    }
                );

                // 清除模拟流间隔
                clearInterval(simulatedStreamInterval);

                // 获取响应内容 - 确保返回的是字符串
                const content = response.choices?.[0]?.message?.content || '';
                if (typeof content !== 'string') {
                    console.error('API返回了非字符串内容:', content);
                    throw new Error('API返回了无效的响应格式');
                }

                console.log(`收到响应, 长度: ${content.length}`);

                // 模拟打字停顿
                await new Promise(resolve => setTimeout(resolve, 800));

                // 发送实际响应来替换模拟响应
                streamCallback('\n\n----\n\n');

                // 将实际响应分成小块并模拟打字效果
                const chunks = splitIntoChunks(content, 3);
                for (const chunk of chunks) {
                    await new Promise(resolve => setTimeout(resolve, 50 + Math.random() * 50));
                    streamCallback(chunk);
        }

        return {
            success: true,
                    content,
                    response
                };
            } catch (error) {
                console.error('API请求失败:', error);

                // 清除模拟流间隔
                clearInterval(simulatedStreamInterval);

                // 发送错误消息到流
                streamCallback('\n\n请求失败：');
                streamCallback(`\n\n${handleApiError(error, modelName)}`);

                return {
                    success: false,
                    error: handleApiError(error, modelName)
                };
            }
        } else {
            // 不使用流式响应
            try {
                console.log(`发送API请求: model=${modelName}, temperature=${options.temperature}, maxTokens=${options.maxTokens}`);

                // 转换消息格式
                const formattedMessages = messages.map(msg => ({
                    role: msg.role === 'user' ? 'user' : (msg.role === 'system' ? 'system' : 'assistant'),
                    content: typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content)
                }));

                const response = await callApiDirectly(
                    modelName,
                    formattedMessages,
                    {
                        temperature: options.temperature || defaultOptions.temperature,
                        max_tokens: options.maxTokens || defaultOptions.maxTokens,
                        stream: false
                    }
                );

                // 获取响应内容
                const content = response.choices?.[0]?.message?.content || '';
                if (typeof content !== 'string') {
                    console.error('API返回了非字符串内容:', content);
                    throw new Error('API返回了无效的响应格式');
                }

                console.log(`收到响应, 长度: ${content.length}`);

                return {
                    success: true,
                    content,
                    response
                };
            } catch (error) {
                console.error('API请求失败:', error);
                return {
                    success: false,
                    error: handleApiError(error, modelName)
                };
            }
        }
    } catch (error) {
        console.error('生成AI响应发生错误:', error);
        return {
            success: false,
            error: `生成AI响应失败: ${error instanceof Error ? error.message : String(error)}`
        };
    }
}

/**
 * 生成AI响应 - 旧版本，保留以兼容现有代码
 * @param messages 消息历史
 * @param options 请求选项
 * @returns AI响应
 */
export async function generateAIResponseOld(
    messages: ChatMessage[],
    options: AIRequestOptions = {}
): Promise<AIResponse> {
    // 调用新函数实现
    return generateAIResponse(messages, options) as Promise<AIResponse>;
}

/**
 * 实现对话前缀续写功能，用于长回复被截断后的续写
 * @param model 模型名称
 * @param prefix 被截断的内容前缀
 * @param apiKey API密钥
 * @param context 对话上下文消息
 * @returns 续写结果
 */
export async function continueChatCompletion(
    model: string,
    prefix: string,
    apiKey: string,
    context: ChatMessage[] = []
): Promise<AIResponse> {
    try {
        // 确保API初始化完成
        const initialized = await ensureApiInitialized();
        if (!initialized) {
            return {
                success: false,
                error: '无法初始化API服务'
            };
        }

        // 获取invoke函数
        const invoke = getInvoke();

        // 创建前缀续写消息
        const prefixMessage: ChatMessage = {
            role: 'assistant',
            content: prefix
        };

        // 构建完整消息列表，添加前缀标记
        const messages = [
            ...context,
            { ...prefixMessage, prefix: true } as any // 添加prefix标记
        ];

        // 选择适合当前模型的API命令和基础URL
        const provider = getProviderForModel(model).toLowerCase();
        let apiCommand = 'call_ai_api';
        // 前缀续写必须使用Beta API
        const baseUrl = 'https://api.deepseek.com/beta';

        if (provider === 'deepseek') {
            apiCommand = 'call_deepseek_api';
        } else if (provider === 'siliconflow' ||
            ['zhipu', 'glm', 'yi', 'qwen', 'moonshot', 'baichuan'].some(name => provider.includes(name))) {
            apiCommand = 'call_siliconflow_api';
        }

        // 构建请求体
        const requestBody = {
            model: model,
            messages: messages,
            temperature: 0.7,
            max_tokens: 4000 // 续写使用较大的token数
        };

        // 创建请求选项字符串
        const requestOptionsStr = JSON.stringify(requestBody);

        console.log(`发送前缀续写请求到${provider} API(${baseUrl})，模型: ${model}，前缀长度: ${prefix.length}`);

        // 调用API，添加base_url参数
        const result = await invoke(apiCommand, {
            apiKey,
            model: model,
            base_url: baseUrl,
            request_options: requestOptionsStr
        });

        // 检查结果
        if (!result.success) {
            console.error(`前缀续写请求失败:`, result.error);
            return {
                success: false,
                error: getHumanReadableError(result.error, model)
            };
        }

        // 组合前缀和续写内容
        const completeContent = prefix + result.content;

        return {
            success: true,
            response: completeContent,
            content: completeContent
        };

    } catch (error) {
        console.error('前缀续写请求失败:', error);
        return {
            success: false,
            error: `续写请求出错: ${error instanceof Error ? error.message : String(error)}`
        };
    }
} 